package com.demo.juc.volat;


/**
 * @Author: shubin_yao
 * @Date: 2022/05/08/17:38
 * @Description: Volatile 可见性
 * <p>
 * A、B 两个线程 , 本案例 A --》A 线程、main -》B
 * volatile  可见性：保证可见性其实就是：修改通知
 *           原子性：不保证原子性： 保证数据完整性，要不同时成功要不同时失败，就是操作不能覆盖
 *           有序性：禁止指令重排序
 */
class VolatileDemo {
    public static void main(String[] args) {

        Mydata mydata = new Mydata();

        //可见性测试
   /*     new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);  //保证 main 拿到 number==0
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            mydata.add();
            System.out.println(Thread.currentThread().getName() + "\t" + mydata.number);
        }, "A").start();

        while (mydata.number == 0) {

        }

        System.out.println(Thread.currentThread().getName() + "\t" + mydata.number);
*/

        //原子性测试
        for (int i = 0; i < 20; i++) {
            new Thread(() -> {
                for (int j = 0; j < 1000; j++) {
                    mydata.addPlus();
                }
            }, String.valueOf(i)).start();
        }

        //保证线程执行完了
        while (Thread.activeCount() > 2) {
            Thread.yield();
        }
        System.out.println("final  result:" + mydata.number);

    }
}


class Mydata {
    //int number = 0;  //不加volatile
    volatile int number = 0;  //加volatile

    void add() {
        number = 60;
    }

    /*void addPlus() {
        number++;
    }*/

    synchronized void addPlus() {
        number++;
    }
}